package cn.ai.shoes.core.controller;

import cn.ai.shoes.common.exception.ServiceException;
import cn.ai.shoes.common.exception.constant.GlobalErrorCodeConstants;
import cn.ai.shoes.common.pojo.entity.CommonResult;
import cn.ai.shoes.core.annotation.AddGroup;
import cn.ai.shoes.core.annotation.OpLog;
import cn.ai.shoes.core.annotation.UpdateGroup;
import cn.ai.shoes.common.utils.RedisUtils;
import cn.ai.shoes.core.pojo.entity.InvitationCode;
import cn.ai.shoes.core.pojo.entity.MyUser;
import cn.ai.shoes.core.service.InvitationCodeService;
import cn.ai.shoes.core.service.UserService;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.annotation.Resource;
import jodd.util.StringUtil;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.sql.SQLIntegrityConstraintViolationException;
import java.time.LocalDateTime;

import static cn.ai.shoes.common.constant.GolbalConstants.OpTypeConstants.OP_INSERT;
import static cn.ai.shoes.common.constant.GolbalConstants.OpTypeConstants.OP_UPDATE;
import static cn.ai.shoes.common.constant.GolbalConstants.UserConstants.MEMBER;
import static cn.ai.shoes.common.constant.GolbalConstants.UserConstants.VISITOR;
import static cn.ai.shoes.common.exception.constant.GlobalErrorCodeConstants.*;
import static cn.ai.shoes.core.controller.LoginController.SMS_CODE_KEY;


@RestController
@RequestMapping("/user")
@Tag(name = "用户个人信息",description = "用户-用户管理接口")
public class UserController {
    @Resource
    private UserService userService;
    @Resource
    private InvitationCodeService invitationCodeService;
    @Resource
    private RedisUtils<String,String> redisUtils;

    /**
     * 注册用户
     * @param myUser
     * @return
     */

    @PostMapping("/register")
    @Operation(summary = "注册用户",description = "注册用户")
    @OpLog(OP_INSERT)
    public CommonResult register(@RequestBody @Validated MyUser myUser){
        System.out.println("[注册调试] myUser = " + myUser);
        //获取验证码
        String redisPhone = redisUtils.get(SMS_CODE_KEY + myUser.getSmsCode());
        if (StringUtil.isEmpty(redisPhone)) {
            return CommonResult.error(GlobalErrorCodeConstants.SMS_CODE_ERROR);
        }
        if (!redisPhone.equals(myUser.getPhone())){
            return CommonResult.error(GlobalErrorCodeConstants.SMS_CODE_ERROR);
        }
        //查询数据库中是否存在该用户
        QueryWrapper<MyUser> queryWrapper = new QueryWrapper<MyUser>().eq("phone", myUser.getPhone());
        MyUser dbMyUser = userService.getOne(queryWrapper);
        //如果存在，返回错误信息
        if (dbMyUser != null) {
            return CommonResult.error(GlobalErrorCodeConstants.USER_EXIST);
        }
        //删除
        redisUtils.del(SMS_CODE_KEY + myUser.getSmsCode());
        // 密码加密
        BCryptPasswordEncoder encoder = new BCryptPasswordEncoder();
        myUser.setPassword(encoder.encode(myUser.getPassword()));
        myUser.setRole(VISITOR);
        // 新增：注册用户默认启用
        myUser.setEnabled(true);
        //生成用户唯一标识
        myUser.setUid(java.util.UUID.randomUUID().toString().replace("-", ""));
        myUser.isEnabled();
        try {
            userService.save(myUser);
        } catch (RuntimeException e) {
            if (e.getCause() instanceof SQLIntegrityConstraintViolationException) {
                return CommonResult.error(GlobalErrorCodeConstants.USERNAME_EXISTS);
            }else {
                e.printStackTrace();
                return CommonResult.error(GlobalErrorCodeConstants.USER_REGISTER_ERROR);
            }
        }
        return CommonResult.success();
    }
    /**
     * 修改用户信息
     * @param myUser
     * @return
     */
    @PutMapping("/update")
    @Operation(summary = "修改用户信息",description = "修改用户信息")
    @OpLog(OP_UPDATE)
    public CommonResult update(@RequestBody @Validated({UpdateGroup.class}) MyUser myUser){
        //查询用户信息
        MyUser myUser1 = userService.getById(myUser.getId());
        if (myUser1 == null) {
            return CommonResult.error(USER_NOT_EXIST);
        }
        //判断用户唯一标识是否一致
        if (!myUser1.getUid().equals(myUser.getUid())) {
            return CommonResult.error(USER_NO_PERMISSION);
        }
        UserDetails userDetails = User.withDefaultPasswordEncoder()
                .username(myUser.getUsername())
                .password(myUser.getPassword())
                .build();
        myUser.setPassword(userDetails.getPassword());
        userService.updateById(myUser);
        return CommonResult.success();
    }
    /**
     * 根据邀请码升级用户权限
     * @param id
     * @return
     */
    @PutMapping("/upgrade/{id}/{code}")
    @Operation(summary = "根据邀请码升级用户权限",description = "根据邀请码升级用户权限")
    public CommonResult upgrade(@PathVariable @Schema(description = "用户id") Integer id,@PathVariable @Schema(description = "邀请码id") String code){
        QueryWrapper<InvitationCode> code1 = new QueryWrapper<InvitationCode>().eq("code", code);
        //查询邀请码信息
        InvitationCode invitationCode = invitationCodeService.getOne(code1);
        //查询用户信息
        MyUser myUser = userService.getById(id);
        //判断邀请码是否存在
        if (invitationCode == null) {
            return CommonResult.error(INVITATION_CODE_NOT_EXIST);
        }
        //判断邀请码是否已使用
        if (invitationCode.getIsActive()==1) {
            return CommonResult.error(INVITATION_CODE_USED);
        }
        //判断邀请码是否过期
        if (LocalDateTime.now().isAfter(invitationCode.getExpiresAt())) {
            return CommonResult.error(INVITATION_CODE_EXPIRED);
        }
        //判断用户是否存在
        if (myUser == null) {
            return CommonResult.error(USER_NOT_EXIST);
        }
        //判断用户权限是否为访客
        if (myUser.getRole().equals(VISITOR)) {
            myUser.setRole("MEMBER");
            // 获取当前时间（LocalDateTime格式）
            //到期时间设置当前时间（LocalDateTime格式）加上邀请码可使用时间
            myUser.setExpireTime(LocalDateTime.now().plusDays(invitationCode.getUsedAt()));
            userService.updateById(myUser);
            //更新邀请码状态为已使用
            invitationCode.setIsActive(1);
            invitationCodeService.updateById(invitationCode);
            return CommonResult.success();
        }else {
            LocalDateTime userExpireTime = myUser.getExpireTime();
            //判断用户到期时间是否为空
            if (userExpireTime == null) {
                userExpireTime = LocalDateTime.now();
            }
            //到期时间设置当前时间（LocalDateTime格式）加上邀请码可使用时间
            myUser.setExpireTime(userExpireTime.plusDays(invitationCode.getUsedAt()));
            userService.updateById(myUser);
            //更新邀请码状态为已使用
            invitationCode.setIsActive(1);
            invitationCodeService.updateById(invitationCode);
            return CommonResult.success();
        }
    }
    /**
     * 查询用户信息
     * @return
     */
    @GetMapping("/info")
    @Operation(summary = "查询用户信息",description = "查询用户信息")
    public CommonResult get(){
        //获取当前登录用户信息
        MyUser myUser = (MyUser) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
        //查询用户信息
        myUser = userService.getById(myUser.getId());
        if (myUser == null) {
            return CommonResult.error(USER_NOT_EXIST);
        }
        myUser.setPassword(null);
        myUser.setSmsCode(null);
        return CommonResult.success(myUser);
    }

}
